package org.ims.inv.service.system.impl;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.ims.inv.dao.system.DAOAppUser;
import org.ims.inv.model.system.ModelAppUser;
import org.ims.inv.model.system.ModelAppUserProfile;
import org.ims.inv.service.system.ServiceAppUser;

import cn.trymore.core.exception.DAOException;
import cn.trymore.core.exception.ServiceException;
import cn.trymore.core.service.impl.ServiceGenericImpl;
import cn.trymore.core.util.UtilCollection;
import cn.trymore.core.util.UtilString;
import cn.trymore.core.web.paging.PaginationSupport;
import cn.trymore.core.web.paging.PagingBean;

/**
 * Service: 系统用户
 * 
 * @author Jeccy.Zhao
 *
 */
public class ServiceAppUserImpl
extends ServiceGenericImpl<ModelAppUser> implements ServiceAppUser
{
	/**
	 * The repository of application user.
	 */
	private DAOAppUser daoAppUser;
	
	public ServiceAppUserImpl(DAOAppUser dao)
	{
		super(dao);
		this.daoAppUser = dao;
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.ims.inv.service.system.ServiceAppUser#findByUserName(java.lang.String)
	 */
	@Override
	public ModelAppUser findByUserName (String userName) throws ServiceException
	{
		try
		{
			return this.daoAppUser.findByUserName(userName);
		} 
		catch (Exception e)
		{
			throw new ServiceException(e);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.ims.inv.service.system.ServiceAppUser#findByUserRole(java.lang.String)
	 */
	@Override
	public List<ModelAppUser> findByUserRole (String roleKey) throws ServiceException
	{
		try
		{
			DetachedCriteria criteria = DetachedCriteria.forClass(ModelAppUser.class);
			criteria.createCriteria("userRole").add(Restrictions.like("roleKey", roleKey, MatchMode.ANYWHERE));
			return this.getByCriterion(criteria);
		} 
		catch (Exception e)
		{
			throw new ServiceException(e);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.ims.inv.service.system.ServiceAppUser#findByUserIDs(java.lang.String[])
	 */
	@Override
	public List<ModelAppUser> findByUserIDs (String[] userIds) throws ServiceException
	{
		if (userIds != null && userIds.length > 0)
		{
			DetachedCriteria criteria = this.getCriterias(null);
			criteria.add(Restrictions.sqlRestriction("u_id in (" + UtilString.join(userIds, ",") + ")"));
			return this.getByCriterion(criteria);
		}
		else
		{
			return null;
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.ims.inv.service.system.ServiceAppUser#findByUserNo(java.lang.String)
	 */
	@Override
	public ModelAppUser findByUserNo (String userNo) throws ServiceException
	{
		try
		{
			if (UtilString.isNotEmpty(userNo))
			{
				ModelAppUser entity = new ModelAppUser();
				entity.setUserNo(userNo);
				
				DetachedCriteria criteria = this.getCriterias(entity);
				List<ModelAppUser> user = this.daoAppUser.getListByCriteria(criteria);
				
				if (UtilCollection.isNotEmpty(user))
				{
					if (user.size() == 1)
					{
						return user.get(0);
					}
					else
					{
						throw new ServiceException("Multi-users returned when searching by no.");
					}
				}
				
				return null;
			}
			else
			{
				throw new ServiceException("User no not provided.");
			}
		} 
		catch (Exception e)
		{
			throw new ServiceException(e);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.ims.inv.service.system.ServiceAppUser#getPasswordByUserName(java.lang.String)
	 */
	@Override
	public ModelAppUser getPasswordByUserName(String userName)
			throws ServiceException
	{
		try 
		{
			 return daoAppUser.getPasswordByUserName(userName);
		} 
		catch (DAOException e) 
		{
			throw new ServiceException(e);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.ims.inv.service.system.ServiceAppUser#removeUser(java.lang.String)
	 */
	public void removeUser (String uid) throws ServiceException
	{
		try
		{
			ModelAppUser entity = this.daoAppUser.get(uid);
			if (entity != null)
			{
				entity.setDelFlag(ModelAppUser.FLAG_DEL);
				this.daoAppUser.saveOrUpdate(entity);
			}
			else
			{
				throw new ServiceException("Account entity does not exist with id: " + uid);
			}
		}
		catch (DAOException e)
		{
			throw new ServiceException(e);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.ims.inv.service.system.ServiceAppUser#getAllUsers()
	 */
	@Override
	public List<ModelAppUser> getAllUsers () throws ServiceException
	{
		try
		{
			ModelAppUser entity = new ModelAppUser();
			entity.setSuperFilter(true);
			
			return this.daoAppUser.getListByCriteria(this.getCriterias(entity));
		}
		catch (DAOException e)
		{
			throw new ServiceException(e);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see cn.trymore.core.service.impl.ServiceGenericImpl#getCriterias(cn.trymore.core.model.ModelBase)
	 */
	protected DetachedCriteria getCriterias(ModelAppUser entity)
	{
		DetachedCriteria criteria = DetachedCriteria.forClass(ModelAppUser.class);
		
		if (entity != null)
		{
			if (UtilString.isNotEmpty(entity.getUsername()))
			{
				criteria.add(Restrictions.like("username", entity.getUsername(), MatchMode.ANYWHERE));
			}
			
			if (UtilString.isNotEmpty(entity.getUserNo()))
			{
				criteria.add(Restrictions.eq("userNo", entity.getUserNo()));
			}
			
			if (entity.isSuperFilter() != null && entity.isSuperFilter())
			{
				// 过滤超级管理员账号
				criteria.add(Restrictions.ne("username", ModelAppUser.SUPER_USER_NAME));
			}
			
			if (entity.getUserProfile() != null)
			{
				if (entity.getUserProfile().getDepartment() != null)
				{
					criteria.createCriteria("userProfile").createCriteria("department").add(
							Restrictions.eq("id", entity.getUserProfile().getDepartment().getId()));
				}
			}
			
		}
		
		// 过滤已删除的用户账号...
		criteria.add(Restrictions.or(
				Restrictions.eq("delFlag", ModelAppUser.FLAG_UNDEL), 
				Restrictions.isNull("delFlag")));
		
		return criteria;
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.ims.inv.service.system.ServiceAppUser#findByUserNameORUserNo(java.lang.String)
	 */
	@Override
	public List<ModelAppUser> findByUserNameORUserNo (String search)
			throws ServiceException
	{
		try
		{
			DetachedCriteria criteria = this.getCriterias(null);
			if (UtilString.isNotEmpty(search))
			{
				criteria.add(Restrictions.or(
					Restrictions.like("username", search, MatchMode.ANYWHERE), 
					Restrictions.like("userNo", search, MatchMode.ANYWHERE)
				));
			}
			
			// 过滤被冻结账号
			criteria.add(Restrictions.eq("userStatus", ModelAppUser.STAT_NORMAL));
			
			return this.daoAppUser.getListByCriteria(criteria);
		}
		catch (DAOException e)
		{
			throw new ServiceException(e);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.ims.inv.service.system.ServiceAppUser#findByUserProfile(org.ims.inv.model.system.ModelAppUserProfile, cn.trymore.core.web.paging.PagingBean)
	 */
	@Override
	public PaginationSupport<ModelAppUser> findByUserProfile(
			ModelAppUserProfile profile, PagingBean pagingBean)
			throws ServiceException
	{
		if (profile != null)
		{
			try
			{
				ModelAppUser user = new ModelAppUser();
				user.setUserProfile(profile);
				user.setSuperFilter(true);
				
				return this.daoAppUser.findPageByCriteria(this.getCriterias(user), pagingBean);
			}
			catch (DAOException e)
			{
				throw new ServiceException(e);
			}
		}
		return null;
	}

}
